<?php
declare(strict_types=1);

namespace app\admin\controller;

use app\common\controller\AdminController;
use app\common\utils\JsonResponse;
use think\App;
use app\admin\validate\RoleValidate;
use think\facade\Request;
use app\common\model\Role as RoleModel;
use think\facade\Db;
use app\common\model\Menu as MenuModel;

class Role extends AdminController
{
    protected RoleModel $roleModel;
    
    public function __construct(App $app)
    {
        parent::__construct($app);
        $this->roleModel = new RoleModel();
    }
    
    /**
     * 获取角色列表
     * @permission system:role:getList
     */
    public function getList()
    {
        $params = Request::get();
        
        try {
            // 标准化分页参数
            $pageNo = isset($params['pageNo']) ? intval($params['pageNo']) : 1;
            $pageSize = isset($params['pageSize']) ? intval($params['pageSize']) : 10;
            
            // 查询条件
            $where = [];
            if (!empty($params['name'])) {
                $where[] = ['name', 'like', "%{$params['name']}%"];
            }
            if (isset($params['status']) && $params['status'] !== '') {
                $where[] = ['status', '=', intval($params['status'])];
            }
            
            // 查询列表，使用 with 预加载菜单关联
            $list = $this->roleModel->with(['roleMenu'])
                ->where($where)
                ->field('role_id,name,code,status,remark,create_time,update_time')
                ->order('role_id', 'asc')
                ->paginate([
                    'list_rows' => $pageSize,
                    'page' => $pageNo
                ])
                ->each(function($item) {
                    // 获取角色菜单ID
                    $item['menu_ids'] = $item->roleMenu->column('menu_id');
                    // 获取菜单路由
                    $menuModel = new MenuModel();
                    $item['menus'] = $menuModel->getRouters([$item['code']]);
                    // 删除 roleMenu 字段
                    unset($item['roleMenu']);
                    return $item;
                });
                
            return JsonResponse::successPaginate($list);
        } catch (\Exception $e) {
            return JsonResponse::error($e->getMessage());
        }
    }
    
    /**
     * 添加角色
     * @permission system:role:doAdd
     */
    public function doAdd()
    {
        $params = Request::post();
        
        try {
            validate(RoleValidate::class)
                ->scene('add')
                ->check($params);
                
            // 检查角色标识是否存在
            if ($this->roleModel->where('code', $params['code'])->find()) {
                return JsonResponse::error('角色标识已存在');
            }
            
            // 开启事务
            Db::startTrans();
            try {
                $data = [
                    'name' => $params['name'],
                    'code' => $params['code'],
                    'status' => $params['status'] ?? 1,
                    'remark' => $params['remark'] ?? ''
                ];
                
                // 保存角色信息
                if (!$this->roleModel->save($data)) {
                    throw new \Exception('添加角色失败');
                }
                
                // 保存菜单关联
                if (!empty($params['menu_ids'])) {
                    $menuData = [];
                    foreach ($params['menu_ids'] as $menuId) {
                        $menuData[] = [
                            'role_id' => $this->roleModel->role_id,
                            'menu_id' => $menuId
                        ];
                    }
                    if (!empty($menuData)) {
                        Db::name('role_menu')->insertAll($menuData);
                    }
                }
                
                Db::commit();
                return JsonResponse::success([], '添加成功');
                
            } catch (\Exception $e) {
                Db::rollback();
                throw $e;
            }
            
        } catch (\think\exception\ValidateException $e) {
            return JsonResponse::error($e->getMessage());
        } catch (\Exception $e) {
            return JsonResponse::error($e->getMessage());
        }
    }
    
    /**
     * 修改角色
     * @permission system:role:doEdit
     */
    public function doEdit()
    {
        $params = Request::post();
        
        try {
            validate(RoleValidate::class)
                ->scene('edit')
                ->check($params);
                
            $role = $this->roleModel->find($params['role_id']);
            if (!$role) {
                return JsonResponse::error('角色不存在');
            }
            
            // 检查角色标识是否被其他角色使用
            if ($this->roleModel->where('code', $params['code'])
                ->where('role_id', '<>', $params['role_id'])
                ->find()) {
                return JsonResponse::error('角色标识已存在');
            }
            
            // 开启事务
            Db::startTrans();
            try {
                $data = [
                    'name' => $params['name'],
                    'code' => $params['code'],
                    'status' => $params['status'] ?? 1,
                    'remark' => $params['remark'] ?? ''
                ];
                
                // 更新角色信息
                if (!$role->save($data)) {
                    throw new \Exception('修改角色失败');
                }
                
                // 更新菜单关联
                if (isset($params['menu_ids'])) {
                    // 删除原有菜单关联
                    Db::name('role_menu')->where('role_id', $params['role_id'])->delete();
                    
                    // 添加新的菜单关联
                    if (!empty($params['menu_ids'])) {
                        $menuData = [];
                        foreach ($params['menu_ids'] as $menuId) {
                            $menuData[] = [
                                'role_id' => $params['role_id'],
                                'menu_id' => $menuId
                            ];
                        }
                        if (!empty($menuData)) {
                            Db::name('role_menu')->insertAll($menuData);
                        }
                    }
                }
                
                Db::commit();
                return JsonResponse::success([], '修改成功');
                
            } catch (\Exception $e) {
                Db::rollback();
                throw $e;
            }
            
        } catch (\think\exception\ValidateException $e) {
            return JsonResponse::error($e->getMessage());
        } catch (\Exception $e) {
            return JsonResponse::error($e->getMessage());
        }
    }
    
    /**
     * 删除角色
     * @permission system:role:doDelete
     */
    public function doDelete()
    {
        $params = Request::post();
        
        try {
            $role = $this->roleModel->find($params['role_id']);
            if (!$role) {
                return JsonResponse::error('角色不存在');
            }
            
            // 检查是否有管理员使用此角色
            $count = Db::name('admin_role')
                ->where('role_id', $params['role_id'])
                ->count();
            if ($count > 0) {
                return JsonResponse::error('该角色已被管理员使用，无法删除');
            }
            
            if ($role->delete()) {
                // 删除角色菜单关联
                Db::name('role_menu')->where('role_id', $params['role_id'])->delete();
                return JsonResponse::success([], '删除成功');
            }
            return JsonResponse::error('删除失败');
            
        } catch (\Exception $e) {
            return JsonResponse::error($e->getMessage());
        }
    }
} 